Data races are intermittent bugs that arise in concurrent programs. They result in incorrect behavior under certain interleavings of the code, and are hard to find and debug. The most common definition of a data race is two concurrent accesses to a memory location with no synchronization between them where at least one of which is a write. This definition has two shortcomings. First, there is a circularity in that synchronization is what we use to prevent data races, so defining races in terms of synchronization is unsatisfying. Second, a program in which every access is protected can nevertheless display problematic interleavings. This is the case when the granularity of locking is not adequate. An example of these “high-level” data races is stale-value errors, local copies of shared variables that are used beyond an appropriate scope. See M. Burrows and K. R. M. Leino. “Finding stale-value errors in concurrent programs”. SRC Technical Note 2002-004, May 2002. Therefore there is a need for a system and method of ensuring consistency of data and preventing data races that avoids the shortcomings of prior approaches.